{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "调试梯度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "#数据准备\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "x=np.random.random(size=(1000,10))#1000行数据，10个特征\n",
    "True_theta=np.arange(1,12,dtype=float)\n",
    "X_b=np.hstack([np.ones((len(x),1)),x])\n",
    "y=X_b.dot(True_theta)+np.random.normal(size=1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "def J(theta,X_b,y):#损失函数\n",
    "    try:\n",
    "        return np.sum((y-X_b.dot(theta))**2)/len(y)\n",
    "    except:\n",
    "        return float(\"inf\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "def dJ_math(theta,X_b,y):#批量梯度下降\n",
    "    return X_b.T.dot(X_b.dot(theta)-y)*2./len(y)#向量化计算：2/m*X_bT(X_bθ-y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "#梯度调整函数\n",
    "def dJ_debug(theta,X_b,y,epsilon=0.00001):\n",
    "    res=np.empty(len(theta))\n",
    "    for i in range(len(theta)):\n",
    "        theta_1=theta.copy()\n",
    "        theta_1[i]=theta_1[i]+epsilon#θ+ε\n",
    "        theta_2=theta.copy()\n",
    "        theta_2[i]=theta_2[i]-epsilon#θ-ε\n",
    "        res[i]=(J(theta_1,X_b,y)-J(theta_2,X_b,y))/(2*epsilon)#对θi的导数=【J(θi+)-J(θi-)】/2ε\n",
    "    return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "#梯度下降训练算法\n",
    "def gradient_descent(dJ,X_b,y,initail_theta,eta,n_iters=1e4,epsilon=1e-8):\n",
    "    theta=initail_theta\n",
    "    cur_iter=0\n",
    "    while cur_iter<n_iters:\n",
    "        gradient=dJ(theta,X_b,y)\n",
    "        last_theta=theta\n",
    "        theta=theta-eta*gradient\n",
    "        if (abs(J(theta,X_b,y)-J(last_theta,X_b,y))<epsilon):\n",
    "            break\n",
    "        cur_iter=cur_iter+1\n",
    "    return theta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: total: 34.4 s\n",
      "Wall time: 23.7 s\n"
     ]
    }
   ],
   "source": [
    "X_b=np.hstack([np.ones((len(x),1)),x])\n",
    "initial_theta=np.zeros(X_b.shape[1])\n",
    "eta=0.01\n",
    "%time theta=gradient_descent(dJ_debug,X_b,y,initial_theta,eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: total: 5.72 s\n",
      "Wall time: 3.84 s\n"
     ]
    }
   ],
   "source": [
    "%time theta_math=gradient_descent(dJ_math,X_b,y,initial_theta,eta)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.92237082,  2.13813173,  3.02763506,  4.25154254,  4.91759684,\n",
       "        5.9524785 ,  7.04766942,  8.09611426,  8.9066499 , 10.0385381 ,\n",
       "       10.75836285])"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.92237082,  2.13813173,  3.02763506,  4.25154254,  4.91759684,\n",
       "        5.9524785 ,  7.04766942,  8.09611426,  8.9066499 , 10.0385381 ,\n",
       "       10.75836285])"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "theta_math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
